package com.batchengine.util;

import com.batchengine.service.Service;

import java.io.*;
import java.net.Socket;

/**
 * Created by sunil.incubator@yahoo.com.
 * User: sunil.kalva
 * Date: Jul 11, 2009
 */
public class ConnectionHandler extends Thread {

    /**
     * Fully qualified class name
     */
    private static final String FQCN = ConnectionHandler.class.getName();

    protected Socket socket;
    protected Service service;
    protected String password;

    protected InputStream in;
    protected OutputStream out;

    /**
     * Creates a <tt>ConnectionHandler</tt> for a service that does not require authentication.
     *
     * @param socket  the socket corresponding to the connection
     * @param service the service requested for the connection
     */
    public ConnectionHandler(Socket socket, Service service) {
        this(socket, service, null);
    }

    /**
     * Creates a <tt>ConnectionHandler</tt> for a service that requires password authentication.
     *
     * @param socket   the socket corresponding to the connection
     * @param service  the service requested for the connection
     * @param password the true password used for comparing with the password entered by the user
     */
    public ConnectionHandler(Socket socket, Service service, String password) {
        this.socket = socket;
        this.service = service;
        this.password = password;
    }

    /**
     * Autheticates the user. It prompts the user for a password and verifies the password.
     *
     * @return true            if authentication succeeded
     * @throws java.io.IOException if an I/O error occurs
     */
    public boolean authenticate() throws IOException {

        PrintWriter writer = new PrintWriter(out, true);
        writer.print("Password: ");
        writer.flush();
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        String line = reader.readLine();
        if (line == null) {
            return false;
        }
        if (line.equals(password)) {
            writer.println("Password authentication succeeded.");
            return true;
        } else {
            writer.println("Password authentication failed.");
            return false;
        }
    }

    /**
     * This method autheticates the user, if necessary, and calls the <tt>service</tt> method of the requested
     * <tt>Service</tt>.
     */
    public void run() {

        try {

            in = socket.getInputStream();
            out = socket.getOutputStream();

            if (service.requiresAuthentication() && !authenticate()) {
                return;
            }

            service.service(in, out);

        } catch (IOException ioe) {
        } finally {
            try {
                socket.close();
            } catch (IOException ioe) {
                // Ignore exception from closing sockets.
            }
        }
    }
}